//
// TextWindow.m
// Copyright (c) 1990 by Jiro Nakamura 
// All rights reserved
//
// Handles a window with a scroll view in it, opens it with a filename,
// lets the user modify it,
//  and if anything changes, lets she or he save it before
// closing it.
//
//	by Jiro Nakamura (ac6y@vax5.cit.cornell.edu)
//
// RCS Information
// Revision Number->	$Revision: 2.15 $
// Last Revised->	$Date: 90/12/03 01:56:35 $
//
static char rcsid[] = "$Id: TextWindow.m,v 2.15 90/12/03 01:56:35 jiro Exp Locker: jiro $";

#import "TextWindow.h"
#import <sys/file.h>
#import <appkit/ScrollView.h>
#import <appkit/Text.h>
#import <appkit/Window.h>
#import "cass.h"			// for default FONTSIZE and FONTNAME			
#import <libc.h>			/* for open and close */
#import <appkit/Panel.h>	/* for NXRunAlertPanel */

@implementation TextWindow
+ new
{
	self = [super new];
	filename = "";				// Default values
	windowIcon = "";
	[self setTitle: "Window"];
	return self;
}

- free
{
	[self performClose : self];
	[super free];
	return self;
}

- setFilename: (const char *) file;
{
	filename = file;
	return self;
}

- setWindowIcon: (const char *) name;
{
	windowIcon = name;
	return self;
}


- (const char *) filename
{
	return filename;
}

- (const char *) windowIcon
{
	[self setMiniwindowIcon: windowIcon];
	return windowIcon;
}

- openWith: (const char *) file
{
	filename = 	file;
	textView = 	[textScroll docView];
	[textView 	setDelegate : self];
	[textView	setMonoFont: NO];
	[self 		setMiniwindowIcon: windowIcon];

	/* If we are not visible, then we need to do an update after */
	/* making ourselves the key window. */
	if( ![self isVisible])		
		{
		[self makeKeyAndOrderFront : self];
		[self update];
		}
	else
		[self makeKeyAndOrderFront : self];

    return self;
}

- close
{	
	#ifdef DEBUG
		fprintf(stderr,"Window <%s> about to close. Checking save.\n"
				"IsDocEdited = %s, IsVisible = %s.\n",
				[self title],
				[self isDocEdited]?"Yes":"No",
				[self isVisible]?"Yes":"No");
	#endif
	[self save];
	[self setDocEdited: NO];
	[textView becomeFirstResponder];
	if( [self isVisible] )
		[super close];
	return self;
}

- save
{
	int fd;
	NXStream	*output; 
		
	if( [self isDocEdited] || [self isVisible] )
		{
		// If the text is zero length then let us delete it.
		if( [textView textLength] == 0)
			{
			#ifdef DEBUG
				fprintf(stderr, "Deleting %s because "
						"it's empty.\n",
						filename);
			#endif
			unlink(filename);
			}
		else
			{
			#ifdef DEBUG
				fprintf(stderr, "Saving %s.\n",
					filename);
			#endif
			// Create and truncate file to zero
			fd = open(filename, O_TRUNC | O_CREAT, 0600);
			close(fd);
			output = NXMapFile(filename, NX_WRITEONLY);
			[textView writeRichText:output]; 
			NXSaveToFile(output, filename);
			NXCloseMemory(output, NX_FREEBUFFER); 
			[self setDocEdited: NO];
			[textView becomeFirstResponder];
			}
		}
	return self;
}


// Re-read the file in and display it on the view (if it is visible, that is)
- update
{
	if( [self isVisible])
		{
		NXStream	*input; 

		if( (input = NXMapFile( filename, NX_READONLY)) == NULL)
			{
			[textView selectAll: self];
			[textView setText: ""];
			[textView setSel: 0 : 0];
			}	
		else
			{
			[textView readRichText:input]; 
			NXCloseMemory(input, NX_FREEBUFFER); 
			}
			
		[self setDocEdited: NO];
		[textView setSel: 0 : 0];
		}
	return self;
}

- printPSCode: sender
{
	[textView printPSCode: self];
	return self;
}

// This moves the current selection to the end of the text
- selectTextEnd: sender
{
	[textView setSel: [textView textLength] : [textView textLength]]; 
	[textView scrollSelToVisible];
	return self;
}


// This is a delegate method. We are our own delegate.
// Let's us change the close button's shape if we have
// been edited.
- textDidChange : object
{
	[self setDocEdited: YES];
	[textView becomeFirstResponder];
	return self;
}

- textWillConvert:textObject  fromFont:from toFont:to
{
	[self setDocEdited: YES];
	[textView becomeFirstResponder];
	return to;
}

- setDocEdited: (BOOL) flag
{
	#ifdef AUTOSAVE	
		hasChanged = flag;
		return self;
	#else
		return( [super setDocEdited: flag]);
	#endif
}

- (BOOL) isDocEdited
{
	#ifdef AUTOSAVE	
		return hasChanged;
	#else
		return( [super isDocEdited]); 
	#endif
	
}
@end
